Imports System.Drawing.Drawing2D

Public Class Button
	Inherits System.Windows.Forms.Button

	Dim HasMouse As Boolean
	Dim IsClicked As Boolean
	Dim WithEvents Timer As Timer
	Dim Watch As Stopwatch

	Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
		If keyData = Keys.Enter Then
			IsClicked = True
			Invalidate()
		End If
		Return MyBase.ProcessDialogKey(keyData)
	End Function

	Private Sub Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click
		IsClicked = False
	End Sub

	Private Sub Button_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
		Watch = Stopwatch.StartNew
		Timer.Enabled = True	'm_Flash
	End Sub

	Private Sub Button_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LostFocus
		Timer.Enabled = False
		Watch = Nothing
		Invalidate()
	End Sub

	Private Sub Button_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
		If e.Button = Windows.Forms.MouseButtons.Left Then
			IsClicked = True
		End If
	End Sub

	Private Sub Button_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseEnter
		HasMouse = True
	End Sub

	Private Sub Button_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseLeave
		HasMouse = False
	End Sub

	Private Sub Button_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
		IsClicked = False
		Invalidate()
	End Sub

	Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
		e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
		Dim R = ClientRectangle
		e.Graphics.Clear(Themes.Current.FormColor)
		Renderer.PaintButton(e.Graphics, R, Me, IsClicked, HasMouse Or Focused, False, Enabled, False)
		R.Inflate(-1, -1)
		e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
		e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality
		R.Inflate(1, 1)
		Dim ImgMargin As Integer = 0
		Dim TextColor As Color = SystemColors.WindowText
		Dim ButtonText As String = Replace(Text, "&", "")
		If Not Enabled Then TextColor = Color.FromArgb(128, Color.Black)
		Dim Format As New StringFormat
		Format.LineAlignment = StringAlignment.Center
		If ImageKey <> "" Then
			ImgMargin = (Height - 16) / 2
			DrawImage(e.Graphics, New Rectangle(ImgMargin, ImgMargin, 16, 16), ImageKey, If(Enabled, 255, 64))
			Format.Alignment = StringAlignment.Near
			DrawStringLighted(e.Graphics, ButtonText, Font, TextColor, New Rectangle(Height - ImgMargin, 1, Width - Height + ImgMargin, Height), Format)
		Else
			Format.Alignment = StringAlignment.Center
			DrawStringLighted(e.Graphics, ButtonText, Font, TextColor, New Rectangle(0, 1, Width, Height), Format)
		End If
	End Sub

	Sub DrawImage(ByVal G As Graphics, ByVal R As Rectangle, ByVal Key As String, ByVal Opacity As Integer)
		R.Inflate(-2, -2)
		Select Case Key
			Case "new"
				Dim p(9) As Point
				For i = 0 To 9
					Dim rd = If((i Mod 2) = 1, R.Width / 2, R.Width / 4)
					Dim an As Double = 36 / (180 / Math.PI) * i
					p(i) = New Point(R.Left + R.Width / 2 + rd * Math.Cos(an), R.Top + R.Height / 2 + rd * Math.Sin(an))
				Next
				Dim Path As New GraphicsPath
				Path.AddLines(p) : Path.CloseFigure()
				G.FillPath(New SolidBrush(Color.FromArgb(Opacity, Color.Yellow)), Path)
				G.DrawPath(New Pen(Color.FromArgb(Opacity * 3 / 4, Color.Black), 1), Path)
			Case "close"
				Dim Pen As New Pen(Color.FromArgb(Opacity, Color.DarkRed), 1)
				G.DrawEllipse(Pen, R)
				R.Inflate(-2, -2)
				G.DrawLine(Pen, R.Left, R.Bottom, R.Right, R.Top)
			Case "continue"
				R.Inflate(-3, -2)
				Dim Triangle(2) As PointF
				Triangle(0) = New Point(R.Right, R.Top + R.Height / 2)
				Triangle(1) = New Point(R.Left, R.Top)
				Triangle(2) = New Point(R.Left, R.Bottom)
				Dim Path As New GraphicsPath(Triangle, New Byte() {1, 1, 1})
				G.FillPolygon(New SolidBrush(Color.FromArgb(Opacity, Color.Yellow)), Triangle)
				G.DrawPolygon(New Pen(Color.FromArgb(Opacity * 3 / 4, Color.Black), 1), Triangle)
			Case "next"
				R.Inflate(-3, -2)
				Dim Triangle(2) As PointF
				Triangle(0) = New Point(R.Right, R.Top + R.Height / 2)
				Triangle(1) = New Point(R.Left, R.Top)
				Triangle(2) = New Point(R.Left, R.Bottom)
				Dim Path As New GraphicsPath(Triangle, New Byte() {1, 1, 1})
				G.FillPolygon(New SolidBrush(Color.FromArgb(Opacity, Color.Black)), Triangle)
			Case "prev"
				R.Inflate(-3, -2)
				Dim Triangle(2) As PointF
				Triangle(0) = New Point(R.Left, R.Top + R.Height / 2)
				Triangle(1) = New Point(R.Right, R.Top)
				Triangle(2) = New Point(R.Right, R.Bottom)
				Dim Path As New GraphicsPath(Triangle, New Byte() {1, 1, 1})
				G.FillPolygon(New SolidBrush(Color.FromArgb(Opacity, Color.Black)), Triangle)
			Case "save"
				R.Inflate(-2, -2)
				Dim Pen As New Pen(Color.FromArgb(Opacity, Color.DarkGreen), 2)
				Pen.StartCap = LineCap.Round
				Pen.EndCap = LineCap.Round
				G.DrawLine(Pen, R.Left, CInt(R.Top + R.Height / 2), CInt(R.Left + R.Width / 4), R.Bottom)
				G.DrawLine(Pen, CInt(R.Left + R.Width / 4), R.Bottom, R.Right, R.Top)
			Case "cancel"
				R.Inflate(-2, -2)
				Dim Pen As New Pen(Color.FromArgb(Opacity, Color.DarkRed), 2)
				Pen.StartCap = LineCap.Round
				Pen.EndCap = LineCap.Round
				G.DrawLine(Pen, R.Left, R.Top, R.Right, R.Bottom)
				G.DrawLine(Pen, R.Left, R.Bottom, R.Right, R.Top)
			Case "help"
				Dim Pen As New Pen(Color.FromArgb(Opacity, Color.DarkGreen), 1)
				G.FillEllipse(New SolidBrush(Color.FromArgb(Opacity, Color.White)), R)
				G.DrawEllipse(Pen, R)
				R.Inflate(-2, -2)
				G.FillEllipse(LGBv(R, Color.FromArgb(Opacity, Color.Yellow), Color.FromArgb(Opacity, Color.DarkGreen)), R)
				G.DrawEllipse(Pen, R)
				'R.Inflate(-2, -2)
				'G.FillEllipse(New SolidBrush(Color.FromArgb(Opacity, Color.DarkGreen)), R)
			Case "reset"
				'R.Inflate(-1, -1)
				G.PixelOffsetMode = PixelOffsetMode.HighQuality
				Dim Pen As New Pen(Color.FromArgb(Opacity, Color.DarkBlue), 1)
				Dim xc As Double = R.Left + R.Width / 2
				Dim yc As Double = R.Top + R.Height / 2
				Dim radius As Double = R.Width / 2
				For angle As Double = Math.PI / 12 To 2 * Math.PI Step Math.PI / 6
					G.DrawLine(Pen, CSng(xc + 4 * Math.Sin(angle)), CSng(yc + 4 * Math.Cos(angle)), CSng(xc + radius * Math.Sin(angle)), CSng(yc + radius * Math.Cos(angle)))
				Next
				G.PixelOffsetMode = PixelOffsetMode.None
			Case "import"
				R.Inflate(-2, -3)
				Dim Triangle(2) As PointF
				Triangle(0) = New Point(R.Left + R.Width / 2, R.Top)
				Triangle(1) = New Point(R.Right, R.Bottom)
				Triangle(2) = New Point(R.Left, R.Bottom)
				Dim Path As New GraphicsPath(Triangle, New Byte() {1, 1, 1})
				G.FillPolygon(New SolidBrush(Color.FromArgb(Opacity, Color.Black)), Triangle)
			Case "export"
				R.Inflate(-2, -3)
				Dim Triangle(2) As PointF
				Triangle(0) = New Point(R.Left + R.Width / 2, R.Bottom)
				Triangle(1) = New Point(R.Right, R.Top)
				Triangle(2) = New Point(R.Left, R.Top)
				Dim Path As New GraphicsPath(Triangle, New Byte() {1, 1, 1})
				G.FillPolygon(New SolidBrush(Color.FromArgb(Opacity, Color.Black)), Triangle)
			Case "copy"
				R.Inflate(-3, 1)
				R.Offset(-1, -1)
				For i As Integer = 1 To 2
					G.FillRectangle(New SolidBrush(Color.FromArgb(Opacity, Color.White)), R)
					G.DrawRectangle(New Pen(Color.FromArgb(Opacity, Color.Black)), R)
					R.Inflate(-2, -2)
					Dim Pen As New Pen(Color.FromArgb(Opacity / 2, Color.Black), 1)
					For y As Integer = R.Top To R.Bottom Step 2
						G.DrawLine(Pen, R.Left, y, R.Right, y)
					Next
					R.Inflate(2, 2)
					R.Offset(2, 2)
				Next
			Case "add"
				R.Inflate(-3, -3)
				Dim Pen As New Pen(Color.FromArgb(Opacity, Color.DarkBlue), 2)
				Pen.StartCap = LineCap.Round
				Pen.EndCap = LineCap.Round
				G.DrawLine(Pen, CInt(R.Left + R.Width / 2), R.Top, CInt(R.Left + R.Width / 2), R.Bottom)
				G.DrawLine(Pen, R.Left, CInt(R.Top + R.Height / 2), R.Right, CInt(R.Top + R.Height / 2))
			Case "edit"
				R.Inflate(-2, -2)
				Dim Pen(3) As PointF
				Dim PW As Integer = R.Width / 5
				Dim Alpha As Integer = 255
				Pen(0) = New Point(R.Right - PW, R.Top)
				Pen(1) = New Point(R.Left, R.Bottom - PW)
				Pen(2) = New Point(R.Left + PW, R.Bottom)
				Pen(3) = New Point(R.Right, R.Top + PW)
				'G.FillPolygon(LGBd(R, Color.FromArgb(0, Color.White), Color.FromArgb(Alpha, Color.Black)), Pen)
				G.DrawPolygon(New Pen(Color.FromArgb(Alpha, Color.Black)), Pen)
				Dim Triangle(2) As PointF
				Triangle(0) = New Point(R.Left, R.Bottom - PW)
				Triangle(1) = New Point(R.Left - 2, R.Bottom + 2)
				Triangle(2) = New Point(R.Left + PW, R.Bottom)
				'G.FillPolygon(LGBd(R, Color.FromArgb(Alpha, Color.White), Color.FromArgb(Alpha, Color.White)), Triangle)
				G.DrawPolygon(New Pen(Color.FromArgb(Alpha, Color.Black)), Triangle)
			Case "delete"
				R.Inflate(-2, -2)
				Dim Pen As New Pen(Color.FromArgb(Opacity, Color.DarkRed), 2)
				Pen.StartCap = LineCap.Round
				Pen.EndCap = LineCap.Round
				G.DrawLine(Pen, R.Left, R.Top, R.Right, R.Bottom)
				G.DrawLine(Pen, R.Left, R.Bottom, R.Right, R.Top)
			Case "report"
				R.Inflate(-1, 0)
				G.FillRectangle(New SolidBrush(Color.FromArgb(Opacity, Color.White)), R)
				G.DrawRectangle(New Pen(Color.FromArgb(Opacity * 3 / 4, Color.Black)), R)
				R.Inflate(-2, -2)
				Dim Pen As New Pen(Color.FromArgb(Opacity / 2, Color.Black), 1)
				For y As Integer = R.Top To R.Bottom Step 2
					G.DrawLine(Pen, R.Left, y, R.Right, y)
				Next
		End Select
	End Sub

	Overloads WriteOnly Property Active() As Boolean
		Set(ByVal Value As Boolean)
			Enabled = Value
		End Set
	End Property

	Dim m_Visible As Boolean
	Shadows Property Visible() As Boolean
		Get
			Return m_Visible
		End Get
		Set(ByVal Value As Boolean)
			m_Visible = Value
			MyBase.Visible = Value
		End Set
	End Property

	Public Sub New()
		Font = H1Font
		Timer = New Timer
		Timer.Enabled = False
		Timer.Interval = 40
		DoubleBuffered = True
		'BackColor = Color.Transparent
		Cursor = Cursors.Hand
	End Sub

	Private Sub Timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer.Tick
		Invalidate()
	End Sub

	Dim m_Flash As Boolean
	Property Flash() As Boolean
		Get
			Return m_Flash
		End Get
		Set(ByVal Value As Boolean)
			m_Flash = Value
		End Set
	End Property

	Private Sub Button_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.TextChanged
		Invalidate()
	End Sub

End Class
